<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ShopCode\Action\Dashboard;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\Rbac\Middleware\PermissionMiddleware;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkContact\Contract\WorkContactTagPivotContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Plugin\ShopCode\Contract\ShopCodeContract;

/**
 * 门店活码-数据分析-客户数据.
 * @Controller
 */
class ShowContact extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Inject
     * @var ShopCodeContract
     */
    protected $shopCodeService;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContactService;

    /**
     * @Inject
     * @var WorkContactTagPivotContract
     */
    protected $workContactTagPivotService;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    protected $logger;

    /**
     * @var int
     */
    protected $perPage;

    /**
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class),
     *     @Middleware(PermissionMiddleware::class)
     * })
     * @RequestMapping(path="/dashboard/shopCode/showContact", methods="get")
     */
    public function handle(): array
    {
        // 验证接受参数
        $params = $this->request->all();
        $this->validated($params);
        // 获取当前登录用户
        $user = user();

        // 判断用户绑定企业信息
        if (! isset($user['corpIds']) || count($user['corpIds']) != 1) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }

        // 接收参数
        $params = [
            'corpId' => $user['corpIds'][0],
            'type' => $this->request->input('type'),
            'contactName' => $this->request->input('contactName'),
            'employeeId' => $this->request->input('employeeId'),
            'startTime' => $this->request->input('start_time'),
            'endTime' => $this->request->input('end_time'),
            'shopName' => $this->request->input('shopName'),
            'status' => $this->request->input('status'),
            'province' => $this->request->input('province'),
            'city' => $this->request->input('city'),
            'page' => $this->request->input('page', 1),
            'perPage' => $this->request->input('perPage', 10000),
        ];

        // 店主
        if ((int) $params['type'] === 1) {
            return $this->shop($params);
        }
        // 2、门店群  3、城市群
        return $this->shopRoom($params);
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
            'type' => 'required | integer | bail',
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
            'type.required' => '类型 必填',
            'type.integer' => '类型 必须为整型',
        ];
    }

    /**
     * 店主.
     * @throws \JsonException
     */
    private function shop(array $params): array
    {
        // 查询门店
        $shopList = $this->searchShop($params);
        if (empty($shopList)) {
            return [];
        }

        $shopState = [];
        foreach ($shopList as $k => $v) {
            $shopState[] = 'shopCode-' . $v['id'];
        }

        // 查询客户
        $contactList = $this->searchContact($params, $shopState);

        $list = [];
        $data = [
            'page' => [
                'perPage' => $this->perPage,
                'total' => '0',
                'totalPage' => '0',
            ],
            'list' => $list,
        ];

        return empty($contactList['data']) ? $data : $this->handleData($contactList, $shopList);
    }

    /**
     * 门店群.
     * @throws \JsonException
     */
    private function shopRoom(array $params): array
    {
        // 查询门店
        $shopList = $this->searchShop($params);
        if (empty($shopList)) {
            return [];
        }

        $shopState = [];
        foreach ($shopList as $k => $v) {
            $qwCode = Json::decode($v['qwCode']);
            $workRoomAutoPullId = $qwCode['workRoomAutoPullId'];
            $shopState[] = 'workRoomAutoPullId-' . $workRoomAutoPullId;
        }

        // 查询客户
        $contactList = $this->searchContact($params, $shopState);

        $list = [];
        $data = [
            'page' => [
                'perPage' => $this->perPage,
                'total' => '0',
                'totalPage' => '0',
            ],
            'list' => $list,
        ];

        return empty($contactList['data']) ? $data : $this->handleData($contactList, $shopList);
    }

    private function searchShop(array $params): array
    {
        $shopSearch = [
            'corpId' => $params['corpId'],
            'type' => $params['type'],
            'name' => $params['shopName'],
            'employeeId' => $params['employeeId'],
            'province' => $params['province'],
            'city' => $params['city'],
        ];
        return $this->shopCodeService->getShopCodeBySearch($shopSearch, ['id', 'name', 'employee', 'address', 'country', 'province', 'city']);
    }

    private function searchContact(array $params, array $shopState): array
    {
        $search = [
            'corpId' => $params['corpId'],
            'state' => $shopState,
            'startTime' => $params['startTime'],
            'endTime' => $params['endTime'],
            'status' => $params['status'],
            'withTrashed' => 1,
            'page' => $params['page'],
            'perPage' => $params['perPage'],
        ];
        return $this->workContactEmployeeService->getWorkContactEmployeesBySearch($search, ['contact_id', 'state', 'status', 'create_time']);
    }

    /**
     * 数据处理.
     * @param array $contactList 列表数据
     * @return array 响应数组
     * @throws \JsonException
     */
    private function handleData(array $contactList, array $shopList): array
    {
        $contactIds = array_column($contactList['data'], 'contactId');
        $contacts = $this->workContactService->getWorkContactsById($contactIds, ['id', 'name', 'avatar']);
        $contacts = array_column($contacts, null, 'id');
        $shopList = array_column($shopList, null, 'id');
        $list = [];

        foreach ($contactList['data'] as $key => $val) {
            $tag = $this->workContactTagPivotService->getWorkContactTagPivotsNameByContactId($val['contactId']);
            $state = explode('-', $val['state']);
            $shopId = (int) $state[1];
            $list[$key] = [
                'contactId' => $val['contactId'],
                'contactName' => empty($contacts[$val['contactId']]) ? '未知' : $contacts[$val['contactId']]['name'],
                'avatar' => empty($contacts[$val['contactId']]) ? '未知' : file_full_url($contacts[$val['contactId']]['avatar']),
                'employee' => empty($shopList[$shopId]) ? '{}' : Json::decode($shopList[$shopId]['employee']),
                'createdAt' => $val['createTime'],
                'shopName' => empty($shopList[$shopId]) ? '未知' : $shopList[$shopId]['name'],
                'tag' => $tag,
                'address' => empty($shopList[$shopId]) ? '未知' : $shopList[$shopId]['address'],
                'province' => empty($shopList[$shopId]) ? '未知' : $shopList[$shopId]['province'],
                'city' => empty($shopList[$shopId]) ? '未知' : $shopList[$shopId]['city'],
                'status' => $val['status'],
            ];
        }
        $data['page']['total'] = $contactList['total'];
        $data['page']['totalPage'] = $contactList['last_page'];
        $data['list'] = $list;
        return $data;
    }
}
